package org.abettor.util.struts2.template;

import java.io.StringWriter;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.components.ComponentUrlProvider;
import org.apache.struts2.components.ServletUrlRenderer;
import org.apache.struts2.components.UIBean;
import org.apache.struts2.components.UrlProvider;
import org.apache.struts2.views.util.DefaultUrlHelper;

import com.opensymphony.xwork2.util.ValueStack;

/**
 * 分页标签组件
 * @author shawn
 *
 */
public class PagerComponent extends UIBean
{
	private static final String TEMPLATE_NAME = "pager";
	private static Set<String> keySet = new HashSet<String>();
	private String action;
	private String namespace;
	private int navigationLength;
	private int currentPage;
	private int totalPage;
	private String pagerVariableName;
	static
	{
		keySet.add("templateDir");
		keySet.add("theme");
		keySet.add("dynamicAttributes");
		keySet.add("cssClass");
		keySet.add("cssStyle");
		keySet.add("id");
		keySet.add("escapedId");
	}

	public PagerComponent(ValueStack stack, HttpServletRequest request, HttpServletResponse response)
	{
		super(stack, request, response);
		this.stack = stack;
	}

	@Override
	protected String getDefaultTemplate()
	{
		return TEMPLATE_NAME;
	}

	@SuppressWarnings("unchecked")
	@Override
	protected void evaluateExtraParams()
	{
		super.evaluateExtraParams();

		//	设置参数映射，目前只支持数字和字符串
		List<PagerParameterNode> params = new ArrayList<PagerParameterNode>();
		Map<String, Object> map = getParameters();
		for(String key : map.keySet())
		{
			if(keySet.contains(key))
			{
				continue;
			}

			PagerParameterNode param = new PagerParameterNode();
			param.setName(key);
			param.setValue(map.get(key).toString());
			params.add(param);
		}

		//	计算页码序列
		int left = navigationLength / 2;
		int start = currentPage - left;
		if(start <= 0)
		{
			start = 1;
			left = currentPage - 1;
		}
		int end = navigationLength - left - 1 + currentPage;
		if(end > totalPage)
		{
			start -= end - totalPage;
			if(start <= 0)
			{
				start = 1;
			}

			end = totalPage;
		}

		//	填充页码序列
		List<PagerLinkNode> pageList = new ArrayList<PagerLinkNode>();
		for(int i = start; i <= end; i ++)
		{
			PagerLinkNode node = new PagerLinkNode();
			if(i != currentPage)
			{
				node.setLink(true);
			}
			node.setNumber(i);
			node.setText(i + "");
			pageList.add(node);
		}

		//	首页和上一页
		PagerLinkNode first = new PagerLinkNode();
		PagerLinkNode prev = new PagerLinkNode();
		if(currentPage != 1)
		{
			first.setLink(true);
			prev.setLink(true);
		}
		first.setNumber(1);
		first.setText("<<");
		prev.setNumber(currentPage - 1);
		prev.setText("<");

		//	下一页和尾页
		PagerLinkNode last = new PagerLinkNode();
		PagerLinkNode next = new PagerLinkNode();
		if(currentPage != totalPage)
		{
			last.setLink(true);
			next.setLink(true);
		}
		last.setNumber(totalPage);
		last.setText(">>");
		next.setNumber(currentPage + 1);
		next.setText(">");

		addParameter("actionUri", createUri());
		addParameter("params", params);
		addParameter("pagerVariableName", pagerVariableName);
		addParameter("pageList", pageList);
		addParameter("first", first);
		addParameter("prev", prev);
		addParameter("next", next);
		addParameter("last", last);
	}

	//	构造链接地址
	private String createUri()
	{
		UrlProvider urlProvider = new ComponentUrlProvider(this, null);
		urlProvider.setHttpServletRequest(request);
		urlProvider.setHttpServletResponse(response);
		urlProvider.setAction(action);
		urlProvider.setNamespace(namespace);
		StringWriter sw = new StringWriter();
		ServletUrlRenderer urlRenderer = new ServletUrlRenderer();
		urlRenderer.setUrlHelper(new DefaultUrlHelper());
		urlRenderer.beforeRenderUrl(urlProvider);
		urlRenderer.renderUrl(sw, urlProvider);
		return sw.toString();
	}

	public void setAction(String action)
	{
		this.action = action;
	}

	public void setNamespace(String namespace)
	{
		this.namespace = namespace;
	}

	public void setNavigationLength(int navigationLength)
	{
		this.navigationLength = navigationLength;
	}

	public void setCurrentPage(int currentPage)
	{
		this.currentPage = currentPage;
	}

	public void setTotalPage(int totalPage)
	{
		this.totalPage = totalPage;
	}

	public void setPagerVariableName(String pagerVariableName)
	{
		this.pagerVariableName = pagerVariableName;
	}

	public String getPagerVariableName()
	{
		return pagerVariableName;
	}
}
